namespace GameHelper.Saving.Editor
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    public class CSharpUtil
    {
        /// <summary>
        ///   类型简写
        /// </summary>
        private static Dictionary<Type, string> TypeToShortName = new Dictionary<Type, string> {
            { typeof(bool), "bool" },
            { typeof(byte), "byte" },
            { typeof(sbyte), "sbyte" },
            { typeof(char), "char" },
            { typeof(decimal), "decimal" },
            { typeof(double), "double" },
            { typeof(float), "float" },
            { typeof(int), "int" },
            { typeof(uint), "uint" },
            { typeof(long), "long" },
            { typeof(ulong), "ulong" },
            { typeof(object), "object" },
            { typeof(short), "short" },
            { typeof(ushort), "ushort" },
            { typeof(string), "string" },

            { typeof(bool[]), "bool[]" },
            { typeof(byte[]), "byte[]" },
            { typeof(sbyte[]), "sbyte[]" },
            { typeof(char[]), "char[]" },
            { typeof(decimal[]), "decimal[]" },
            { typeof(double[]), "double[]" },
            { typeof(float[]), "float[]" },
            { typeof(int[]), "int[]" },
            { typeof(uint[]), "uint[]" },
            { typeof(long[]), "long[]" },
            { typeof(ulong[]), "ulong[]" },
            { typeof(object[]), "object[]" },
            { typeof(short[]), "short[]" },
            { typeof(ushort[]), "ushort[]" },
            { typeof(string[]), "string[]" },

            { typeof(bool?), "bool?" },
            { typeof(byte?), "byte?" },
            { typeof(sbyte?), "sbyte?" },
            { typeof(char?), "char?" },
            { typeof(decimal?), "decimal?" },
            { typeof(double?), "double?" },
            { typeof(float?), "float?" },
            { typeof(int?), "int?" },
            { typeof(uint?), "uint?" },
            { typeof(long?), "long?" },
            { typeof(ulong?), "ulong?" },
            { typeof(short?), "short?" },
            { typeof(ushort?), "ushort?" },
        };

        /// <summary>
        /// 反射类型获取到的类型带namespace，常见类型(例如int, float)移除namespace
        /// </summary>
        public static string GetTypeShortName(Type t)
        {
            if (TypeToShortName.TryGetValue(t, out string n))
                return n;
            if (t.IsGenericType)
            {
                var tdef = t.GetGenericTypeDefinition();
                var ret = tdef.ToString();
                var pos = ret.IndexOf('`');
                ret = ret.Substring(0, pos) + "<";
                var args = t.GetGenericArguments();
                if (null != args)
                {
                    var argNames = new List<string>();
                    foreach (var a in args)
                    {
                        argNames.Add(GetTypeShortName(a));
                    }
                    ret += string.Join(", ", argNames);
                }
                ret += ">";
                return ret;
            }
            else
            {
                // 替换嵌套类中的+
                return t.FullName.Replace('+', '.');
            }
        }

        /// <summary>
        ///   Utility
        /// </summary>
        public static IEnumerable<Type> GetTypesWithAttribute<TAttr>(bool inherit) where TAttr : Attribute
        {
            return from a in AppDomain.CurrentDomain.GetAssemblies()
                   from t in a.GetTypes()
                   where t.IsDefined(typeof(TAttr), inherit)
                   select t;
        }
    }
}
